package com.fz.us.admin.company.service.impl;

import com.fz.us.admin.company.bean.EnumManage;
import com.fz.us.admin.company.entity.Admin;
import com.fz.us.admin.company.service.*;
import com.fz.us.admin.base.bean.BaseEnumManager;
import com.fz.us.admin.base.bean.Result;
import com.fz.us.admin.base.bean.SystemConfig;
import com.fz.us.admin.base.bean.search.SearchEnum;
import com.fz.us.admin.base.bean.search.order.Order;
import com.fz.us.admin.base.bean.search.page.PagePaging;
import com.fz.us.admin.base.bean.search.result.SearchResultList;
import com.fz.us.admin.base.bean.search.result.SearchResultPaging;
import com.fz.us.admin.base.bean.search.rule.Rule;
import com.fz.us.admin.base.bean.search.rule.RuleHelper;
import com.fz.us.admin.base.dao.BaseDao;
import com.fz.us.admin.base.service.impl.BaseServiceImpl;
import com.fz.us.admin.base.utils.CommonUtil;
import com.fz.us.admin.base.utils.DataUtil;
import com.fz.us.admin.company.entity.Company;
import com.fz.us.admin.company.entity.Duty;
import com.fz.us.admin.company.mp.WxMpInCacheConfigStorage;
import com.fz.us.admin.company.entity.User;
import com.fz.us.admin.company.dao.UserDao;
import com.fz.us.base.util.Identities;
import com.fz.us.base.util.LogUtil;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * Service实现类 - 用户信息
 * ============================================================================
 * 版权所有 2016 。
 *
 * @author fallenpanda
 * @version 1.0 2016-08-02 。
 * ============================================================================
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User, String> implements UserService {

    @Resource
    private UserDao userDao;
    @Resource
    private WxMpInCacheConfigStorage  wxMpConfigStorage;
    @Resource
    private SystemConfig systemConfig;
    @Resource
    private AdminService adminService;
    @Resource
    private AuthCodeService authCodeService;
    @Resource
    private OrganizeService organizeService;
    @Resource
    private SmsService smsService;

    @Override
    public BaseDao<User, String> getBaseDao() {
        return userDao;
    }
    @Override
    public User getUserByAdminId(String adminId) {
        return userDao.getUserByAdminId(adminId);
    }

    @Override
    public Company getCompanyByUser() {
        User user = getLoginInfo();
        return user.getCompany();
    }

    @Override
    public Company getCompanyByUser(User creater) {
        return creater.getCompany();
    }

    @Override
    public User getLoginInfo() {
        Subject subject= SecurityUtils.getSubject();
        String adminId = (String) subject.getPrincipal();
        User user = userDao.getUserByAdminId(adminId);
        return user;
    }

    @Override
    public List<User> getAllUsers(Company company) {
        return userDao.getAllUsers(company);
    }

    @Override
    public List<User> getAllUsers(Company company, BaseEnumManager.StateEnum... states) {
        return userDao.getAllUsers(company, states);
    }

    @Override
    public User createUser(String name, String adminId) {
        User user = new User();
        user.setName(name);
        user.setAdminId(adminId);

        save(user);
        return user;
    }

    @Override
    public User createUser(String name, String adminId, Company company) {
        User user = new User();
        user.setName(name);
        user.setAdminId(adminId);
        user.setCompany(company);

        save(user);
        return user;
    }

    @Override
    public void deleteUser(User user) {
        user.setAdminId(null);
        user.setState(BaseEnumManager.StateEnum.Delete);

        update(user);
    }

    @Override
    public SearchResultPaging pagingCompanyMember(PagePaging page, List<Rule> rules, Order order, Company company, BaseEnumManager.StateEnum... states) {
        Assert.notNull(company, "company is required");

        if (rules == null)
            rules = new ArrayList<Rule>();
        rules.add(RuleHelper.eq("company", company));
        if (states != null && states.length > 0) {
            rules.add(RuleHelper.in("state", states));
        }

        // 默认排序
        if (order == null)
            order = Order.order("pinYinHead", SearchEnum.OrderType.asc);

        return findPagingBySearch(page, rules, order);
    }

    @Override
    public SearchResultList listCompanyMember(List<Rule> rules, Order order, Company company, BaseEnumManager.StateEnum... states) {
        Assert.notNull(company, "company is required");

        if (rules == null)
            rules = new ArrayList<Rule>();
        rules.add(RuleHelper.eq("company", company));
        if (states != null && states.length > 0) {
            rules.add(RuleHelper.in("state", states));
        }

        // 默认排序
        if (order == null)
            order = Order.order("pinYinHead", SearchEnum.OrderType.asc);

        return findListBySearch(rules, order);
    }

    @Override
    public Result validateAccount(String username) {
        Assert.hasText(username, "username is required");

        EnumManage.AccountEnum accountType = null;
        if (CommonUtil.isMobile(username)) {
            if (adminService.isExistByUsermobile(username)) {
                return resultService.fail("该手机号已被使用");
            }
            accountType = EnumManage.AccountEnum.MOBILE;
        } else if (CommonUtil.isEmail(username)) {
            if (adminService.isExistByUseremail(username)) {
                return resultService.fail("该邮箱已被使用");
            }
            accountType = EnumManage.AccountEnum.MAIL;
        } else {
            if (adminService.isExistByUsername(username)) {
                return resultService.fail("该用户名已被使用");
            }
            accountType = EnumManage.AccountEnum.USERNAME;
        }

        return resultService.success("", accountType);
    }

    @Override
    public Result validPassword(User user, String password) {
        Assert.notNull(user, "user is required");

        if (StringUtils.isEmpty(password))
            return resultService.fail("密码不能为空");

        if (StringUtils.isNotEmpty(user.getAdminId())) {
            Admin admin = adminService.get(user.getAdminId());
            if (admin != null) {
                if(adminService.validPassword(admin, password)) {
                    return resultService.success("校验成功");
                }
                return resultService.fail("密码错误");
            }
        }

        return resultService.fail("用户帐号异常");
    }

    @Override
    public Result resetPasswordByRoleAdmin(User user, User member, String newPassword) {
        Assert.notNull(user, "user is required");
        Assert.notNull(member, "member is required");

        if (StringUtils.isEmpty(newPassword))
            return resultService.fail("新密码不能为空");


        Admin admin = adminService.get(member.getAdminId());
        if (admin != null) {
            return adminService.updatePassword(admin, newPassword);
        }

        return resultService.fail("操作失败");
    }

    @Override
    public Result updatePasswordByPassword(User user, String password, String newPassword) {
        Assert.notNull(user, "user is required");

        if (StringUtils.isEmpty(password))
            return resultService.fail("密码不能为空");
        if (StringUtils.isEmpty(newPassword))
            return resultService.fail("新密码不能为空");

        if (StringUtils.isNotEmpty(user.getAdminId())) {
            Admin admin = adminService.get(user.getAdminId());
            if (admin != null) {
                if(!adminService.validPassword(admin, password)) {
                    return resultService.fail("密码错误");
                }

                return adminService.updatePassword(admin, newPassword);
            }
        }

        return resultService.fail("用户帐号异常");
    }

    @Override
    public Result createMember(String username, String password, String name, Company company) {
        Assert.hasText(username, "username is required");
        Assert.hasText(password, "password is required");
        Assert.hasText(name, "name is required");
        Assert.notNull(company, "company is required");

        Result result = validateAccount(username);
        if (result.getState() == 0) {
            return result;
        }
        EnumManage.AccountEnum accountType = (EnumManage.AccountEnum) result.getData();
        Admin admin = adminService.createAdmin(accountType, EnumManage.AccountTypeEnum.User, username, password);
        if (admin != null) {
            User user = createUser(name, admin.getId(), company);
            return resultService.successWithId(user.getId());
        }

        return resultService.fail("新增成员失败");
    }

    public Map<String, Object> getMemberListMap(User user) {
        Map<String, Object> map = new HashMap<String, Object>();

        map.put("id", StringUtils.isEmpty(user.getId())?"":user.getId());
        map.put("name", StringUtils.isEmpty(user.getName())?"":user.getName());
        map.put("pinYinHead", StringUtils.isEmpty(user.getPinYinHead())?"":user.getPinYinHead().toLowerCase());
        map.put("pinYin", StringUtils.isEmpty(user.getPinYin())?"":user.getPinYin());

        // 账号信息
        StringBuilder account = new StringBuilder();

        // 企业所有者
        Company company = user.getCompany();

        if (StringUtils.isNotEmpty(user.getAdminId())) {
            Admin admin = adminService.get(user.getAdminId());
            if (admin != null) {
                // 帐号
                if (StringUtils.isNotEmpty(admin.getUsername())) {
                    account.append(admin.getUsername());
                }
                if (StringUtils.isNotEmpty(admin.getUsermobile())) {
                    if (account.length() > 0)
                        account.append(" ");
                    account.append(admin.getUsermobile());
                }
                if (StringUtils.isNotEmpty(admin.getUseremail())) {
                    if (account.length() > 0)
                        account.append(" ");
                    account.append(admin.getUseremail());
                }


            }
        }
        map.put("account", account);


        // 岗位信息
        StringBuilder powerId = new StringBuilder();
        StringBuilder powerName = new StringBuilder();
        List<Duty> dutyList = organizeService.getUserDutyList(user);
        for (Duty duty : dutyList) {
            if (powerId.length() > 0) {
                powerId.append(",");
                powerName.append(",");
            }
            powerId.append(duty.getPower().getId());
            powerName.append(duty.getPower().getDepartment().getName()+"-"+duty.getPower().getPost().getName());
        }
        map.put("powerId", powerId);
        map.put("powerName", powerName);

        // other
        map.put("createDate", DataUtil.DateToString(user.getCreateTime()));

        return map;
    }

    /**
     content = "您的登录账号为，"+1+"\n" +
     "绑定/解除绑定账号请点击下面链接：" +
     "<a href=\"http://"+mp_host+"/smartsales/mp/users!account.action?openId="+reqBean.getFromUserName()+"\">账号设置</a>"
     + "";
     * */
    public String getMpAccount(User user,String openId){
        LogUtil.info(openId);
        if(user==null){
            user = getUserByOpenId(openId);
        }
        if(user==null){
            return getLoginContent(openId);
        }
        StringBuffer buffer = new StringBuffer();
        buffer.append("[微笑] "+user.getName()).append("，您好：\n");
        buffer.append("您的账号已绑定成功，点击下面链接： ").append("\n\n");
        buffer.append("<a href=\""+wxMpConfigStorage.getHttpHost()+"/"+systemConfig.getWebroot()+"/mp/account/resetMp?_="+ CommonUtil.getRandomString(8)+"\">设置我的账号</a>").append("\n");

        return buffer.toString();
    }
    /**
     * 得到登录提示语
     * */
    private String getLoginContent(String openId){
        StringBuffer buffer = new StringBuffer();
        buffer.append("[难过]您的微信未绑定正大丰海账号，请绑定或者注册一个新账号。\n");
        buffer.append("<a href=\""+wxMpConfigStorage.getHttpHost()+"/"+systemConfig.getWebroot()+"/mp/login?_="+ Identities.randomBase62(8)+"&openId="+openId+"\">绑定正大丰海账号/体验注册</a>").append("\n\n");
        return buffer.toString();
    }
    public User getUserByOpenId(String openId){
        Admin admin = adminService.getAdminByOpenId(openId);
        if(admin != null){
            return userDao.getUserByAdminId(admin.getId());
        }
        return null;
    }

    @Override
    public String openId(String name) {
        Admin admin = adminService.getAdminByAccount(name);
        if(admin == null){
            return null;
        }
        return admin.getOpenId();
    }

    @Override
    public String openId(User user) {
        Admin admin = adminService.get(user.getAdminId());
        if(admin == null){
            return null;
        }
        return admin.getOpenId();
    }

    @Override
    public Result linkUser(HttpServletResponse httpServletResponse, Admin admin, String tmpOpenId) {
        Result result=new Result();
        if(admin == null){
            result.setState(0);
            return  result;
        }
        Admin tmpAdmin =  adminService.getAdminByOpenId(StringUtils.trim(tmpOpenId));
        String openId = admin.getOpenId();
        if( StringUtils.isNotEmpty(openId)){
            if(StringUtils.trim(openId).equals(StringUtils.trim(tmpOpenId))  ){
                result.setState(1);
            }else{
                result.setState(0);
            }
        }else if(tmpAdmin!=null){
            result.setState(2);
        }else{
            result = adminService.updateOpenId(admin, tmpOpenId);
        }

        return result;
    }

    @Override
    public User getUserByMobile(String mobile) {
        return userDao.getUserByMobile(mobile);
    }

    @Override
    public boolean isWxUsers(String openId) {
        Admin admin = adminService.getAdminByOpenId(openId);
        if(admin != null){
            return  EnumManage.AccountEnum.WEIXIN.equals(admin.getAccountEnum());
        }
        return false;
    }

    @Override
    public Result sendAuthCode(String username, EnumManage.AuthCodeEnum passwordForget, int experience, User user) {
        Result result = checkNameString(username);
        LogUtil.info("{ result }"+result.getData());
        if (result.getState() == 0) {
            return result;
        }
        if (CommonUtil.isMobile(username)) {
            // 检查用户名
            if(1==experience){
                if (StringUtils.equals(EnumManage.AuthCodeEnum.passwordForget.name(), passwordForget.name())) {
                    if (adminService.isExistByUsermobile(username) == false) return resultService.fail("该用户没有注册，请重新输入！");
                } else {
                    if (adminService.isExistByUsermobile(username) == true) return resultService.fail("已经存在该用户，请重新输入！");
                }
            }else{

            }
            //生成验证码
            if(1==experience){
                String random = authCodeService.createAuthCode(username);
                return smsService.send("感谢您对OA系统的支持，您的验证码为："+random + "。", username);
            }else{
                String random = authCodeService.createAuthCode("ty"+username);
                Admin admin  = adminService.get(user.getAdminId());
                return smsService.send("您的验证码为："+random + "。"+"登录帐号:"+admin.getUsermobile()+",密码:"+admin.getPassword(), username);
            }

        }
        return result;
    }



    public Result checkNameString(String name){
        if (StringUtils.isEmpty(name)) {
            return resultService.fail("用户名不能为空！");
        }
        if(!CommonUtil.isMobile(name)){
            return resultService.fail("用户名必须为手机号！");
        }
        return resultService.success();
    }
}
